package fun.codedesign.principle.advice151.a132;

import org.junit.Assert;
import org.junit.Test;

import fun.codedesign.principle.advice151.Good;
import fun.codedesign.principle.advice151.Notice;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 提高java性能的基本方法 <br>
 * <pre>
 * </pre>
 *
 * @author zengjian
 * @create 2018-07-10 9:52
 * @since 1.0.0
 */
@Notice
public class ImproveJavaCode {
    // 建议132. 提高java性能的基本方法

    @Good(item = 2)
    public static final String HELLO = "hello";

    /*
     * 1. 不要在循环条件中进行计算，否则每次循环都需要计算，将增加额外的开销
     * 2. 尽可能把变量方法声明为static final 这些不变化的变量
     * 3. 缩小变量的作用域
     * 4. 频繁字符串操作使用S他ringBuffer 或者StringBuilder
     * 5. 使用非线性搜索，比如用二分查找取代indexOf的遍历查找，但是在查找前需要进行一次排序
     * 6. 覆写Exception的 fillStackTrace方法
     * 7. 不建立冗余的对象（同3，注意作用域）
     */
    @Test
    @Good(item = 1)
    public void test() {
        int[] arr = new int[3];
        for (int i = 0, length = arr.length; i < length; i++) {
            System.out.println(i);
        }
    }

    @Test
    @Good(item = 3)
    public void test2() {
        {
            String a = System.getProperty("java");
            System.out.println(a);
        }

        {
            String a = System.getProperty("ldc");
            System.out.println(a);
        }
    }

    @Good(item = 4)
    @Test
    public void test3() {
        StringBuilder sb = new StringBuilder();
        sb.append("hello").append(" world");
        sb.setLength(0);
        sb.delete(0, sb.length());
        System.out.println(sb.capacity());
    }

    @Good(item = 5)
    @Test
    public void test4() {
        List<Integer> list = new ArrayList<Integer>() {
            {
                add(1);
                add(3);
                add(0);
                add(18);
            }
        };
        Collections.sort(list);
        int index = Collections.binarySearch(list, 18);
        Assert.assertEquals(3, index);
    }

    @Test
    @Good(item = 6)
    public void test6() throws MyException {
        throw new MyException();
    }

}

@Notice("如果在开发时候不需要记录栈信息，可以覆盖此方法")
class MyException extends Exception {
    @Override
    public synchronized Throwable fillInStackTrace() {
        // return super.fillInStackTrace();
        return this;
    }
}
